// 下面为自引用函数
use crate::serial::{self, send_serial};

use core::num;
use std::{array, collections::HashSet, env, fmt::format, fs::{self, read, File, OpenOptions}, io::{BufRead, BufReader, Split, Write}, path::{Path, PathBuf}, time::{Duration, Instant}, vec};
use std::thread::sleep;
use tauri::ipc::InvokeError;
use rusqlite::{Connection, Result};

#[derive(Debug)]
struct Data {
    id: i32,
    name: String,
    data: Option<Vec<u8>>,
}

#[tauri::command]
pub fn link_db() -> Result<String, String> {
    // let conn = Connection::open_in_memory()?;
    // Ok(())

    let mut appdata_path = env::var("APPDATA")
        .map_err(|e| format!("{:?}", e))?;
    
    appdata_path.push_str("\\上肢偏瘫康复机器人");
    let dir_path = PathBuf::from(&appdata_path);

    if !dir_path.exists() {
        fs::create_dir(dir_path.clone()).map_err(|e| format!("{:?}", e))?;
        println!("目录已创建: {:?}", dir_path);
    } else {
        println!("目录已存在: {:?}", dir_path);
    }
    
    appdata_path.push_str("\\user.db");
    let dir_path = PathBuf::from(&appdata_path);
    println!("{:?}",dir_path);
    let conn = Connection::open(&appdata_path)
        .map_err(|_| format!("Connection::open failed"))?;

    conn.execute(
        "CREATE TABLE IF NOT EXISTS torque_history (
            id INTEGER PRIMARY KEY AUTOINCREMENT,
            timestamp TEXT NOT NULL,
            torque REAL NOT NULL,
            device TEXT,
            user_id INTEGER
        )",
        (), // empty list of parameters.
    ).map_err(|_| format!("conn.execute torque_history failed"))?;

    conn.execute(
        "CREATE TABLE IF NOT EXISTS angle_history (
            id INTEGER PRIMARY KEY AUTOINCREMENT,
            timestamp TEXT NOT NULL,
            angle REAL NOT NULL,
            device TEXT,
            user_id INTEGER
        )",
        (), // empty list of parameters.
    ).map_err(|_| format!("conn.execute angle_history failed"))?;

    Ok(format!("目录已存在: {:?}", dir_path))
}

#[tauri::command]
pub fn save_file(filename:String, mo1:Vec<i32>, mo2:Vec<i32>) -> Result<String, String> {
    let mut appdata_path = env::var("APPDATA")
    .map_err(|e| format!("{:?}", e))?;

    appdata_path.push_str("\\上肢偏瘫康复机器人");
    let dir_path = PathBuf::from(&appdata_path);

    if !dir_path.exists() {
        fs::create_dir(dir_path.clone()).map_err(|e| format!("{:?}", e))?;
        println!("目录已创建: {:?}", dir_path);
    } else {
        println!("目录已存在: {:?}", dir_path);
    }

    let temp: String =appdata_path.clone() + "\\" + &filename + "_mo1";
    let dir_path = PathBuf::from(&temp);
    println!("{temp}");
    let mut file = File::create(dir_path.clone()).map_err(|_| format!("File::create failed"))?;

    for item in mo1 {
        writeln!(file, "{}", item).map_err(|_| format!("writeln! failed"))?;
    }

    let temp: String =appdata_path + "\\" + &filename + "_mo2";
    let dir_path = PathBuf::from(&temp);
    let mut file = File::create(dir_path).map_err(|_| format!("File::create failed"))?;
    for item in mo2 {
        writeln!(file, "{}", item).map_err(|_| format!("writeln! failed"))?;
    }

    Ok("save_file OK".to_string())
}

fn load_file(filename:PathBuf) -> Result<Vec<String>, String> {
    let file = File::open(filename.clone()).map_err(|_| format!("File::create failed"))?;

    // 创建 BufReader
    let reader = BufReader::new(file);
    println!("load_file(filename:String):{:?}", reader);

    // 创建一个空的 Vec<String> 来存储每一行
    let mut lines: Vec<String> = Vec::new();
    for line in reader.lines() {
        let line = line.map_err(|_| format!("reader.lines() failed"))?; // 获取当前行的内容
        lines.push(line); // 将当前行压入数组
    }

    println!("{:?}",lines);

    Ok(lines)
}

#[tauri::command]
pub async fn send_data(filename:String, time:u64) -> Result<String, String> {
    let mut appdata_path = env::var("APPDATA")
    .map_err(|e| format!("{:?}", e))?;

    appdata_path.push_str("\\上肢偏瘫康复机器人");

    let temp: String = appdata_path.clone() + "\\" + &filename + "_mo1";
    let dir_path: PathBuf = PathBuf::from(&temp);
    let mo1 = load_file(dir_path)?;

    let temp: String = appdata_path.clone() + "\\" + &filename + "_mo2";
    let dir_path: PathBuf = PathBuf::from(&temp);
    println!("这里是send_data:{:?}",dir_path);
    let mo2 = load_file(dir_path)?;

    println!("这里是send_data:{:?}",mo2);

    let _ = send_serial("e");

    let interval = Duration::from_millis(time);

    let mut temp = String::with_capacity(16); // 预分配足够的空间

    for (index, (a, b)) in mo1.iter().zip(mo2.iter()).enumerate() {
        println!("循环内");
        println!("{} {} {}",index ,a, b);

        sleep(interval);

            temp.clear();
            temp.push_str("a");
            temp.push_str(a);
            temp.push(';');
            let _ = send_serial(&temp);

        // sleep(interval);

            temp.clear();
            temp.push_str("b");
            temp.push_str(b);
            temp.push(';');
            println!("{}",temp);
            let _ = send_serial(&temp);

    }

    let _ = send_serial("f");

    sleep(Duration::from_millis(1000));

    Ok("send_data OK".to_string())
}

#[tauri::command]
pub async fn find_file() -> Result<Vec<String>, String> {
    let mut value:Vec<String> = Vec::new();
    let mut appdata_path = env::var("APPDATA")
    .map_err(|e| format!("{:?}", e))?;

    appdata_path.push_str("\\上肢偏瘫康复机器人");

    let entries = fs::read_dir(appdata_path).map_err(|_| format!("fs::read_dir failed"))?;

    for entry in entries {
        // `entry` 是一个 `Result` 类型，需要处理可能的错误
        let entry = entry.map_err(|_| format!("entry Err"))?;
        // 获取文件名
        let file_name = entry.file_name();
        // 将文件名转换为字符串（如果可能）
        let file_name_str = file_name.into_string().map_err(|_| format!("file_name.into_string() failed"))?;

        println!("{}", file_name_str);

        let file_name_str_parts:Vec<&str> = file_name_str.split("_").collect();

        if file_name_str_parts[0].chars().all(|c| c.is_digit(10)) {
            let mut temp = String::with_capacity(100); // 预分配足够的空间
            temp.push_str(file_name_str_parts[0]);
            temp.push_str("_");
            temp.push_str(file_name_str_parts[1]);
            
            value.push(temp);
        }

    }
    // 使用 HashSet 去重
    let set: HashSet<_> = value.into_iter().collect();
    let retrun_vec: Vec<_> = set.into_iter().collect();

    Ok(retrun_vec)
}

#[tauri::command]
pub async fn delete_file(filename_prefix: u32) -> Result<String, String> {
    let mut appdata_path = env::var("APPDATA")
    .map_err(|e| format!("{:?}", e))?;

    appdata_path.push_str("\\上肢偏瘫康复机器人");

    let prefix = filename_prefix.to_string() + "_";

    let entries = fs::read_dir(appdata_path).map_err(|_| format!("fs::read_dir failed"))?;
    for entry in entries {
        let entry = entry.map_err(|_| format!("entry Err"))?;
        let path = entry.path();

        // 检查是否为文件且文件名以 prefix内容 开头
        if let Some(file_name) = path.file_name().and_then(|s| s.to_str()) {
            if file_name.starts_with(&prefix) && path.is_file() {
                fs::remove_file(&path).map_err(|_| format!("fs::remove_file failed: {:?}", path))?;
            }
        }
    }

    Ok("delete_file OK".to_string())
}

#[tauri::command]
pub async fn get_data_mo1(filename:String) -> Result<Vec<i32>, String> {
    let mut appdata_path = env::var("APPDATA")
    .map_err(|e| format!("{:?}", e))?;

    appdata_path.push_str("\\上肢偏瘫康复机器人");

    let temp: String = appdata_path.clone() + "\\" + &filename + "_mo1";
    let dir_path: PathBuf = PathBuf::from(&temp);
    let mo1 = load_file(dir_path)?;

    let mut mo1arr: Vec<i32> = vec![];

    for (index, a) in mo1.iter().enumerate() {
        println!("循环内");
        println!("{} {}", index, a);

        mo1arr.push(a.parse::<i32>().expect("Failed to parse number"));

    }

    Ok(mo1arr)
}

#[tauri::command]
pub async fn get_data_mo2(filename:String) -> Result<Vec<i32>, String> {
    let mut appdata_path = env::var("APPDATA")
    .map_err(|e| format!("{:?}", e))?;

    appdata_path.push_str("\\上肢偏瘫康复机器人");

    let temp: String = appdata_path.clone() + "\\" + &filename + "_mo2";
    let dir_path: PathBuf = PathBuf::from(&temp);
    let mo2 = load_file(dir_path)?;

    let mut mo2arr: Vec<i32> = vec![];

    for (index, b) in mo2.iter().enumerate() {
        println!("循环内");
        println!("{} {}", index, b);

        mo2arr.push(b.parse::<i32>().expect("Failed to parse number"));

    }

    Ok(mo2arr)
}